﻿#include "MirImageControl.h"
#include "../../Shared/Functions/Functions.h"
#include "../MirGraphics/DXManager.h"

using namespace Client::MirGraphics;

namespace Client::MirControls
{

    Point *MirImageControl::getDisplayLocation() const
    {
        return getUseOffSet() ? Functions::Add(MirControl::getDisplayLocation(), getLibrary()->GetOffSet(getIndex())) : MirControl::getDisplayLocation();
    }

    Point *MirImageControl::getDisplayLocationWithoutOffSet() const
    {
        return MirControl::getDisplayLocation();
    }

    bool MirImageControl::getDrawImage() const
    {
        return _drawImage;
    }

    void MirImageControl::setDrawImage(bool value)
    {
        if (_drawImage == value)
        {
            return;
        }
        _drawImage = value;
        OnDrawImageChanged();
    }

    void MirImageControl::OnDrawImageChanged()
    {
        Redraw();
        if (DrawImageChanged != nullptr)
        {
            DrawImageChanged::Invoke(this, EventArgs::Empty);
        }
    }

    int MirImageControl::getIndex() const
    {
        return _index;
    }

    void MirImageControl::setIndex(int value)
    {
        if (_index == value)
        {
            return;
        }
        _index = value;
        OnIndexChanged();
    }

    void MirImageControl::OnIndexChanged()
    {
        OnSizeChanged();
        if (IndexChanged != nullptr)
        {
            IndexChanged::Invoke(this, EventArgs::Empty);
        }
    }

    MLibrary *MirImageControl::getLibrary() const
    {
        return _library;
    }

    void MirImageControl::setLibrary(MLibrary *value)
    {
        if (_library == value)
        {
            return;
        }
        _library = value;
        OnLibraryChanged();
    }

    void MirImageControl::OnLibraryChanged()
    {
        OnSizeChanged();
        if (LibraryChanged != nullptr)
        {
            LibraryChanged::Invoke(this, EventArgs::Empty);
        }
    }

    void MirImageControl::setPixelDetect(bool value)
    {
        if (_pixelDetect == value)
        {
            return;
        }
        _pixelDetect = value;
        OnPixelDetectChanged();
    }

    void MirImageControl::OnPixelDetectChanged()
    {
        Redraw();
        if (PixelDetectChanged != nullptr)
        {
            PixelDetectChanged::Invoke(this, EventArgs::Empty);
        }
    }

    bool MirImageControl::getUseOffSet() const
    {
        return _useOffSet;
    }

    void MirImageControl::setUseOffSet(bool value)
    {
        if (_useOffSet == value)
        {
            return;
        }
        _useOffSet = value;
        OnUseOffSetChanged();
    }

    void MirImageControl::OnUseOffSetChanged()
    {
        OnLocationChanged();
        if (UseOffSetChanged != nullptr)
        {
            UseOffSetChanged::Invoke(this, EventArgs::Empty);
        }
    }

    void MirImageControl::setSize(Size *value)
    {
        MirControl::setSize(value);
    }

    Size *MirImageControl::getSize() const
    {
        if (getLibrary() != nullptr && getIndex() >= 0)
        {
            return getLibrary()->GetTrueSize(getIndex());
        }
        return MirControl::getSize();
    }

    Size *MirImageControl::getTrueSize() const
    {
        if (getLibrary() != nullptr && getIndex() >= 0)
        {
            return getLibrary()->GetTrueSize(getIndex());
        }
        return MirControl::getTrueSize();
    }

    MirImageControl::MirImageControl()
    {
        _drawImage = true;
        _index = -1;
        setForeColour(Color::White);
    }

    void MirImageControl::DrawControl()
    {
        MirControl::DrawControl();

        if (getDrawImage() && getLibrary() != nullptr)
        {
            bool oldGray = DXManager::GrayScale;

            if (getGrayScale())
            {
                DXManager::SetGrayscale(true);
            }

            if (getBlending())
            {
                getLibrary()->DrawBlend(getIndex(), getDisplayLocation(), getForeColour(), false, getBlendingRate());
            }
            else
            {
                getLibrary()->Draw(getIndex(), getDisplayLocation(), getForeColour(), false, getOpacity());
            }

            if (getGrayScale())
            {
                DXManager::SetGrayscale(oldGray);
            }
        }
    }

    bool MirImageControl::IsMouseOver(Point *p)
    {
        return MirControl::IsMouseOver(p) && (!_pixelDetect || getLibrary()->VisiblePixel(getIndex(), Functions::Subtract(p, getDisplayLocation()),true) || Moving);
    }

    void MirImageControl::Dispose(bool disposing)
    {
        MirControl::Dispose(disposing);

        if (!disposing)
        {
            return;
        }

        DrawImageChanged->addListener("nullptr", nullptr);
        _drawImage = false;

        IndexChanged->addListener("nullptr", nullptr);
        _index = 0;

        LibraryChanged->addListener("nullptr", nullptr);
        setLibrary(nullptr);

        PixelDetectChanged->addListener("nullptr", nullptr);
        _pixelDetect = false;

        UseOffSetChanged->addListener("nullptr", nullptr);
        _useOffSet = false;
    }
}
